﻿Imports System.Xml

'************************************************************************************'
'* Copyright (c) 2009, Patrick Driscoll All rights reserved.                        *'
'*                                                                                  *'
'* Redistribution and use in source and binary forms, with or without               *'
'* modification, are permitted provided that the following conditions are met:      *'
'*                                                                                  *'
'* Redistributions of source code must retain the above copyright notice, this      *'
'* list of conditions and the following disclaimer. Redistributions in binary       *'
'* form must reproduce the above copyright notice, this list of conditions and      *'
'* the following disclaimer in the documentation and/or other materials             *'
'* provided with the distribution. Neither the name of the DriscollArt Software nor *'
'* the names of its contributors may be used to endorse or promote products         *'
'* derived from this software without specific prior written permission.            *'
'*                                                                                  *'
'* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"      *'
'* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE        *'
'* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE       *'
'* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR      *'
'* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL           *'
'* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR       *'
'* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER       *'
'* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT               *'
'* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY        *'
'* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH      *'
'* DAMAGE.                                                                          *'
'************************************************************************************'

''' <summary>
''' Main dialog of the DNNBuilda application
''' </summary>
''' <remarks></remarks>
Public Class Main

    Private Enum TableStatus
        TableOK = 1
        MissingPK = 2
        MissingC = 3
        MissingR = 4
        MissingU = 5
        MissingD = 6
        MissingL = 7
    End Enum
    Private Sub Button_ChooseDNNRoot_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button_ChooseDNNRoot.Click
        FolderBrowserDialog_Main.ShowDialog()
        TextBox_RootDNNPath.Text = FolderBrowserDialog_Main.SelectedPath
    End Sub

    Private Sub Button_GenerateCode_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button_GenerateCode.Click

        Dim strStatusMessage As String = ""

        If ComboBox_Pattern.SelectedIndex = -1 Then
            MsgBox("Please choose a code pattern before generating code.", MsgBoxStyle.OkOnly, "Code Pattern Missing")
            Label_Status.Text = "Code Generation Cancelled."
            ComboBox_Pattern.Focus()
            Exit Sub
        End If

        If TextBox_RootDNNPath.Text.Trim = String.Empty Then
            MsgBox("Please specifiy a root DNN path before generating code.", MsgBoxStyle.OkOnly, "Root Path Missing")
            Label_Status.Text = "Code Generation Cancelled."
            TextBox_RootDNNPath.Focus()
            Exit Sub
        End If

        If DataGridViewFields.RowCount = 1 AndAlso DataGridViewFields.Rows(0).Cells(6).FormattedValue = "" Then
            MsgBox("Please add some database fields before generating code.", MsgBoxStyle.OkOnly, "Fields Missing")
            Label_Status.Text = "Code Generation Cancelled."
            DataGridViewFields.Focus()
            Exit Sub
        End If

        If CaptionsValid() = False Then
            MsgBox("Please add a caption for all fields mapped to controls.", MsgBoxStyle.OkOnly, "Captions Missing")
            Label_Status.Text = "Code Generation Cancelled."
            DataGridViewFields.Focus()
            Exit Sub
        End If

        Label_Status.Text = "Generating Code, Please Wait..."
        Button_GenerateCode.Enabled = False
        Application.DoEvents()
        Select Case DatabaseValid()
            Case TableStatus.TableOK
                strStatusMessage = ""
            Case TableStatus.MissingPK
                strStatusMessage = "You don't have any Primary Key (PK) columns defined. Continue anyway?"
            Case TableStatus.MissingC
                strStatusMessage = "You don't have any (C)reate columns defined. Continue anyway?"
            Case TableStatus.MissingR
                strStatusMessage = "You don't have any (R)ead columns defined. Continue anyway?"
            Case TableStatus.MissingU
                strStatusMessage = "You don't have any (U)pdate columns defined. Continue anyway?"
            Case TableStatus.MissingD
                strStatusMessage = "You don't have any (D)elete columns defined. Continue anyway?"
            Case TableStatus.MissingL
                strStatusMessage = "You don't have any (L)ist columns defined. Continue anyway?"
        End Select

        If strStatusMessage.Length > 0 Then
            If MsgBox(strStatusMessage, MsgBoxStyle.YesNo, "Column Setup") = vbNo Then
                Label_Status.Text = "Code Generation Cancelled."
                Application.DoEvents()
                Button_GenerateCode.Enabled = True
                Exit Sub
            End If
        End If

        Dim xmlDoc As New XmlDocument
        Dim root As XmlElement = xmlDoc.DocumentElement
		xmlDoc.Load(System.AppDomain.CurrentDomain.BaseDirectory & "\templates\templategroups.xml")

		Dim xmlTemplateGroup As XmlNode = xmlDoc.SelectSingleNode("templates/template[name=""" & ComboBox_Pattern.SelectedItem.ToString & """]")
		Dim xmlTemplate As XmlNode
		Dim xmlTemplates As XmlNodeList = xmlTemplateGroup.SelectNodes("files/file")

        For Each xmlTemplate In xmlTemplates
            Label_Status.Text = "Compiling " & xmlTemplate.InnerText & "..."
            Application.DoEvents()
			SaveTemplateCode(xmlTemplate.InnerText, xmlTemplateGroup.Attributes("language").Value)
        Next
        Label_Status.Text &= " Code Generation Complete!"
        Application.DoEvents()
        Button_GenerateCode.Enabled = True

    End Sub

	Private Function GetTemplateCode(ByVal TemplateFileName As String) As String
		Dim objGenerator As New cVBEvalProvider
		Dim sbCode As New System.Text.StringBuilder
		Dim objStreamReader As New System.IO.StreamReader(New System.IO.FileStream(System.AppDomain.CurrentDomain.BaseDirectory & TemplateFileName, IO.FileMode.Open))
		Do Until objStreamReader.EndOfStream
			sbCode.AppendLine(objStreamReader.ReadLine)
		Loop
		objStreamReader.Close()

		Return objGenerator.GenerateDNNCode(sbCode.ToString, BuildDNNProperties, BuildDatabaseProperties)
	End Function

	Private Sub SaveTemplateCode(ByVal TemplateFileName As String, ByVal language As String)
		Dim objGenerator As EvalProvider = Nothing
		Select Case language
			Case "cs"
				objGenerator = New cCSEvalProvider
			Case "vb"
				objGenerator = New cVBEvalProvider
		End Select
		Dim sbCode As New System.Text.StringBuilder
		Dim objStreamReader As New System.IO.StreamReader(New System.IO.FileStream(System.AppDomain.CurrentDomain.BaseDirectory & TemplateFileName, IO.FileMode.Open))
		Do Until objStreamReader.EndOfStream
			sbCode.AppendLine(objStreamReader.ReadLine)
		Loop
		objStreamReader.Close()

		objGenerator.SaveDNNCode(sbCode.ToString, BuildDNNProperties, BuildDatabaseProperties)
	End Sub

    Private Function BuildDNNProperties() As Collection
        Dim DNNProps As New Collection

        DNNProps.Add(TextBox_Namespace.Text, "NameSpace")
        DNNProps.Add(TextBox_RootDNNPath.Text, "RootDNNPath")
        DNNProps.Add(TextBox_ClassName.Text, "ClassName")
        DNNProps.Add(TextBox_SQLTableName.Text, "SQLTableName")
        DNNProps.Add(TextBox_Company.Text, "Company")
        DNNProps.Add(Textbox_Author.Text, "Author")

        Return DNNProps
    End Function

    Private Function BuildDatabaseProperties() As DataTable
        Dim DatabaseProperties As New DataTable("DBProperties")
        Dim objRow As DataRow

        DatabaseProperties.Columns.Add("PK", GetType(System.Boolean))
        DatabaseProperties.Columns.Add("C", GetType(System.Boolean))
        DatabaseProperties.Columns.Add("R", GetType(System.Boolean))
        DatabaseProperties.Columns.Add("U", GetType(System.Boolean))
        DatabaseProperties.Columns.Add("D", GetType(System.Boolean))
        DatabaseProperties.Columns.Add("L", GetType(System.Boolean))
        DatabaseProperties.Columns.Add("fieldname", GetType(System.String))
        DatabaseProperties.Columns.Add("sqldatatype", GetType(System.String))
        DatabaseProperties.Columns.Add("length", GetType(System.String))
        DatabaseProperties.Columns.Add("controltype", GetType(System.String))
        DatabaseProperties.Columns.Add("required", GetType(System.Boolean))
        DatabaseProperties.Columns.Add("fieldcaption", GetType(System.String))
        DatabaseProperties.Columns.Add("helptext", GetType(System.String))
        DatabaseProperties.Columns.Add("validatortext", GetType(System.String))

        For Each objGridRow As DataGridViewRow In DataGridViewFields.Rows
            objRow = DatabaseProperties.NewRow
            objRow.Item("PK") = objGridRow.Cells(0).FormattedValue
            objRow.Item("C") = objGridRow.Cells(1).FormattedValue
            objRow.Item("R") = objGridRow.Cells(2).FormattedValue
            objRow.Item("U") = objGridRow.Cells(3).FormattedValue
            objRow.Item("D") = objGridRow.Cells(4).FormattedValue
            objRow.Item("L") = objGridRow.Cells(5).FormattedValue
            objRow.Item("fieldname") = objGridRow.Cells(6).FormattedValue
            objRow.Item("sqldatatype") = objGridRow.Cells(7).FormattedValue
            objRow.Item("length") = objGridRow.Cells(8).FormattedValue
            objRow.Item("controltype") = objGridRow.Cells(9).FormattedValue
            objRow.Item("required") = objGridRow.Cells(10).FormattedValue
            objRow.Item("fieldcaption") = objGridRow.Cells(11).FormattedValue
            objRow.Item("helptext") = objGridRow.Cells(12).FormattedValue
            objRow.Item("validatortext") = objGridRow.Cells(13).FormattedValue
            DatabaseProperties.Rows.Add(objRow)
        Next

        Return DatabaseProperties
    End Function


    'Private Sub SaveTemplateFile(ByVal TemplateFileName As String)
    '    Dim objGenerator As New cVBEvalProvider
    '    Dim sbCode As New System.Text.StringBuilder
    '    Dim objStreamReader As New System.IO.StreamReader(New System.IO.FileStream(System.AppDomain.CurrentDomain.BaseDirectory & TemplateFileName, IO.FileMode.Open))
    '    Do Until objStreamReader.EndOfStream
    '        sbCode.AppendLine(objStreamReader.ReadLine)
    '    Loop
    '    objStreamReader.Close()

    '    Dim DNNProps As New Collection

    '    DNNProps.Add(TextBox_Namespace.Text, "NameSpace")
    '    DNNProps.Add(TextBox_RootDNNPath.Text, "RootDNNPath")
    '    DNNProps.Add(TextBox_ClassName.Text, "ClassName")
    '    DNNProps.Add(TextBox_SQLTableName.Text, "SQLTableName")
    '    DNNProps.Add(TextBox_Company.Text, "Company")
    '    DNNProps.Add(Textbox_Author.Text, "Author")

    '    Dim DatabaseProperties As New DataTable("DBProperties")
    '    Dim objRow As DataRow


    '    DatabaseProperties.Columns.Add("PK", GetType(System.Boolean))
    '    DatabaseProperties.Columns.Add("C", GetType(System.Boolean))
    '    DatabaseProperties.Columns.Add("R", GetType(System.Boolean))
    '    DatabaseProperties.Columns.Add("U", GetType(System.Boolean))
    '    DatabaseProperties.Columns.Add("D", GetType(System.Boolean))
    '    DatabaseProperties.Columns.Add("L", GetType(System.Boolean))
    '    DatabaseProperties.Columns.Add("fieldname", GetType(System.String))
    '    DatabaseProperties.Columns.Add("sqldatatype", GetType(System.String))
    '    DatabaseProperties.Columns.Add("length", GetType(System.String))

    '    For Each objGridRow As DataGridViewRow In DataGridViewFields.Rows
    '        objRow = DatabaseProperties.NewRow
    '        objRow.Item("PK") = objGridRow.Cells(0).FormattedValue
    '        objRow.Item("C") = objGridRow.Cells(1).FormattedValue
    '        objRow.Item("R") = objGridRow.Cells(2).FormattedValue
    '        objRow.Item("U") = objGridRow.Cells(3).FormattedValue
    '        objRow.Item("D") = objGridRow.Cells(4).FormattedValue
    '        objRow.Item("L") = objGridRow.Cells(5).FormattedValue
    '        objRow.Item("fieldname") = objGridRow.Cells(6).FormattedValue
    '        objRow.Item("sqldatatype") = objGridRow.Cells(7).FormattedValue
    '        objRow.Item("length") = objGridRow.Cells(8).FormattedValue
    '        DatabaseProperties.Rows.Add(objRow)
    '    Next

    '    objGenerator.SaveCodeFile(DNNProps, DatabaseProperties)

    'End Sub

    Private Sub Button_ImportTable_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button_ImportTable.Click
        Dim frmSelectTable As New Dialog_SelectTable
        frmSelectTable.ShowDialog()
        Application.DoEvents()
    End Sub

    Private Sub DataGridViewFields_DataError(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewDataErrorEventArgs) Handles DataGridViewFields.DataError
        'MsgBox(e.Exception.ToString, MsgBoxStyle.OkOnly)
        '  MsgBox("Invalid data for " & e.RowIndex & ", " & e.ColumnIndex & ". ", MsgBoxStyle.OkOnly)
    End Sub

    Private Sub Button_GenerateSQL_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button_GenerateSQL.Click
        Dim frmSQLDialog As New Dialog_CreateSQL

        frmSQLDialog.TextBox_SQLOutput.Text = GetTemplateCode("templates\01.00.00.SQLDataProvider.template")
        frmSQLDialog.TextBox_SQLOutput.Text = frmSQLDialog.TextBox_SQLOutput.Text.Replace("{databaseOwner}", "")
        frmSQLDialog.TextBox_SQLOutput.Text = frmSQLDialog.TextBox_SQLOutput.Text.Replace("{objectQualifier}", "")
        'frmSQLDialog.TextBox_SQLOutput.Text = frmSQLDialog.TextBox_SQLOutput.Text.Replace("GO", ";")
        frmSQLDialog.ShowDialog()
    End Sub

    Private Sub Button_PreviewSection_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button_PreviewSection.Click
        Dim frmPreviewSection As New Dialog_PreviewSection(BuildDatabaseProperties, BuildDNNProperties)
        frmPreviewSection.ShowDialog()
    End Sub

    Private Sub Main_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
        If TextBox_Company.Text.Trim <> String.Empty Then
            My.Settings.CompanyName = TextBox_Company.Text
        End If

        If Textbox_Author.Text.Trim <> String.Empty Then
            My.Settings.Author = Textbox_Author.Text
        End If

        If TextBox_Namespace.Text.Contains(".") Then
            My.Settings.ModulesNamespace = TextBox_Namespace.Text
        End If

        If CheckBox_RememberPath.Checked Then
            My.Settings.LastDNNRootPath = TextBox_RootDNNPath.Text.Trim
        End If
    End Sub

    Private Sub Main_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        If My.Settings.CompanyName <> String.Empty Then
            TextBox_Company.Text = My.Settings.CompanyName
        End If

        If My.Settings.Author <> String.Empty Then
            Textbox_Author.Text = My.Settings.Author
        End If

        If My.Settings.ModulesNamespace <> String.Empty Then
            TextBox_Namespace.Text = My.Settings.ModulesNamespace
        End If

        If My.Settings.LastDNNRootPath <> String.Empty Then
            TextBox_RootDNNPath.Text = My.Settings.LastDNNRootPath
            CheckBox_RememberPath.Checked = True
        End If
        LoadTemplates()
    End Sub

    Private Sub Label_Status_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Label_Status.Click

    End Sub

    Private Sub HelpToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles HelpToolStripMenuItem.Click

    End Sub

    Private Sub OpenTutorialToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles OpenTutorialToolStripMenuItem.Click
        System.Diagnostics.Process.Start("notepad.exe", System.AppDomain.CurrentDomain.BaseDirectory & "tutorial.txt")
    End Sub

    Private Sub AboutToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles AboutToolStripMenuItem.Click
        AboutBox.ShowDialog()
    End Sub

    Private Sub ExitToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ExitToolStripMenuItem.Click
        Application.Exit()
    End Sub

    Private Function DatabaseValid() As TableStatus
        Dim blnPKMissing As Boolean = True
        Dim blnCMissing As Boolean = True
        Dim blnRMissing As Boolean = True
        Dim blnUMissing As Boolean = True
        Dim blnDMissing As Boolean = True
        Dim blnLMissing As Boolean = True
        For Each objGridRow As DataGridViewRow In DataGridViewFields.Rows
            If objGridRow.Cells(0).Value Then
                blnPKMissing = False
            End If

            If objGridRow.Cells(1).Value Then
                blnCMissing = False
            End If

            If objGridRow.Cells(2).Value Then
                blnRMissing = False
            End If

            If objGridRow.Cells(3).Value Then
                blnUMissing = False
            End If

            If objGridRow.Cells(4).Value Then
                blnDMissing = False
            End If

            If objGridRow.Cells(5).Value Then
                blnLMissing = False
            End If
        Next

        If blnPKMissing Then
            Return TableStatus.MissingPK
            Exit Function
        End If

        If blnCMissing Then
            Return TableStatus.MissingC
            Exit Function
        End If

        If blnRMissing Then
            Return TableStatus.MissingR
            Exit Function
        End If

        If blnUMissing Then
            Return TableStatus.MissingU
            Exit Function
        End If

        If blnDMissing Then
            Return TableStatus.MissingD
            Exit Function
        End If

        If blnLMissing Then
            Return TableStatus.MissingL
            Exit Function
        End If

        Return TableStatus.TableOK

    End Function


    Private Function CaptionsValid() As Boolean
        Dim blnCaptionsValid As Boolean = True
        For Each objGridRow As DataGridViewRow In DataGridViewFields.Rows
            If objGridRow.Cells(6).Value <> "" AndAlso objGridRow.Cells(9).Value <> "" AndAlso objGridRow.Cells(11).Value = "" Then
                blnCaptionsValid = False
                Exit For
            End If
        Next

        Return blnCaptionsValid

    End Function
    Private Sub DataGridViewFields_CellContentClick(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles DataGridViewFields.CellContentClick

    End Sub

    Private Sub ClearFieldsToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ClearFieldsToolStripMenuItem.Click
        DataGridViewFields.Rows.Clear()
        Label_Status.Text = "Fields Cleared."
    End Sub

    Private Sub LoadTemplates()
        Try
            Dim xmlDoc As New XmlDocument
            Dim root As XmlElement = xmlDoc.DocumentElement
            xmlDoc.Load(System.AppDomain.CurrentDomain.BaseDirectory & "/templates/templategroups.xml")
            Dim xmlTemplate As XmlNode
            Dim xmlTemplates As XmlNodeList = xmlDoc.SelectNodes("templates/template")
            For Each xmlTemplate In xmlTemplates
                ComboBox_Pattern.Items.Add(xmlTemplate.Item("name").InnerText)
            Next

            ComboBox_Pattern.SelectedIndex = 0
        Catch ex As Exception
            MsgBox(ex.ToString)
        End Try

    End Sub
End Class
